/// 
/// MaDAson - Toolkit for Model Driven Software Development
/// 
/// Copyright [2006] Marcus Lankenau
/// 
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///  
///     http://www.apache.org/licenses/LICENSE-2.0
///  
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
/// 

using System;
using System.Collections;
using System.Text;
using System.Xml.Serialization;

namespace Madason.MetaModel
{
	[Serializable]
	public class Attribute : ModelElement
	{
		private string multiplicity;
		private string initialValue;
		private string typeId;
		private Class @class;


		public string InitialValue
		{
			get { return initialValue; }
			set { initialValue = value; }
		}

		public string Multiplicity
		{
			get { return multiplicity; }
			set { multiplicity = value; }
		}

		[XmlAttribute("type")]
		public string TypeId
		{
			get { return typeId; }
			set { typeId = value; }
		}

		[XmlIgnore]
		public Class Type
		{
			get
			{
				Class type = Class.Model.FindClassById(TypeId);
				/*if (type == null) 
					throw new ApplicationException(
						String.Format("Attribute {0} in Class {1} has no type", Name, Class.Name));
				 */ 
				return type;
			}
		}

		[XmlIgnore]
		public Class Class
		{
			get { return @class; }
			set { @class = value; }
		}
		
		
		[XmlIgnore]
		public string LowercaseGetter			
		{
			get 
			{			
				return "get" + NamePascalCase;
			}
		}

		[XmlIgnore]
		public string LowercaseSetter			
		{
			get 
			{			
				return "set" + NamePascalCase;
			}
		}	
	
	}

	#region Helper Types

	public delegate void AttributeAddDelegate(Attribute ns);


	/// <summary>
	/// List of attributes
	/// </summary>
	public class AttributeList : ArrayList
	{
		public event AttributeAddDelegate AfterAttributeAdded;


		/// <summary>
		/// add attribute
		/// </summary>
		/// <param name="at"></param>
		public void Add(Attribute at)
		{
			base.Add(at);
			if (AfterAttributeAdded != null)
				AfterAttributeAdded(at);
		}


		/// <summary>
		/// find a single attribute by a stereotype
		/// </summary>
		/// <param name="st"></param>
		/// <returns></returns>
		public Attribute FindOneByStereotype(Stereotype st)
		{
			foreach (Attribute attr in this)
				if (attr.Stereotype == st) return attr;
			return null;
		}


		/// <summary>
		/// remove attributes with stereotype of list
		/// </summary>
		/// <param name="st"></param>
		/// <returns></returns>
		public AttributeList RemoveStereotype(Stereotype st)
		{
			AttributeList newList = new AttributeList();
			foreach (Attribute a in this)
				if (a.Stereotype != st) newList.Add(a);
			return newList;
		}

		/// <summary>
		/// access attribute by index
		/// </summary>
		/// <param name="i"></param>
		/// <returns></returns>
		public new Attribute this[int i]
		{
			get
			{
				return base[i] as Attribute;
			}
			set
			{
				base[i] = value;
			}
		}


		/// <summary>
		/// Access attribute via its name
		/// </summary>
		/// <param name="name"></param>
		/// <returns></returns>
		public Attribute this[string name]
		{
			get
			{
				foreach (Attribute attr in this)
					if (attr.Name == name) return attr;
				return null;
			}
		}


		/// <summary>
		/// Is a attribute with a given stereotype included
		/// </summary>
		/// <param name="st"></param>
		/// <returns></returns>
		public bool Contains(Stereotype st)
		{
			foreach (Attribute a in this)
				if (a.Stereotype != st) return true;
			return false;
		}
	}

	#endregion

}
